package com.ruicar.afs.cloud.manage.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.basic.api.corporate.fegin.CorporateTransferFeign;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.manage.common.entity.ManageRevokeHandle;
import com.ruicar.afs.cloud.manage.common.mapper.ManageRevokeHandleMapper;
import com.ruicar.afs.cloud.manage.common.service.ManageRevokeHandleService;
import com.ruicar.afs.cloud.manage.common.util.CreatCaseNoUtil;
import com.ruicar.afs.cloud.manage.revoke.condition.ManageCollectCancelCondition;
import com.ruicar.afs.cloud.manage.revoke.vo.ManageRevokeHandleVo;
import com.ruicar.afs.cloud.manage.workflow.entity.WorkTaskCreatedInfo;
import com.ruicar.afs.cloud.manage.workflow.enums.NormalSubmitEnum;
import com.ruicar.afs.cloud.manage.workflow.enums.WorkflowTypeEnum;
import com.ruicar.afs.cloud.manage.workflow.processor.ContractWorkFlowSaveApproveInfoProcessor;
import com.ruicar.afs.cloud.manage.workflow.service.WorkTaskCreatedInfoService;
import com.ruicar.afs.cloud.manage.workflow.service.WorkflowSubmitService;
import com.ruicar.afs.cloud.manage.workflow.vo.TaskSubmitVO;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author: Lee
 * @date 2020-05-30 04:45:15
 * @description
 */
@Service
@AllArgsConstructor
public class ManageRevokeHandleServiceImpl extends ServiceImpl<ManageRevokeHandleMapper, ManageRevokeHandle> implements ManageRevokeHandleService {
    private final ContractWorkFlowSaveApproveInfoProcessor saveApproveInfoProcessor;
    private final WorkflowService workflowService;
    private final WorkflowSubmitService workflowSubmitService;
    private WorkTaskCreatedInfoService workTaskCreatedInfoService;
    private final ContractWorkFlowSaveApproveInfoProcessor contractWorkFlowSaveApproveInfoProcessor;
    private final CorporateTransferFeign corporateTransferFeign;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean revokedHandleStartProcess(ManageRevokeHandleVo vo) {
        ManageRevokeHandle manageRevokeHandle = this.getOne(Wrappers.<ManageRevokeHandle>lambdaQuery().eq(ManageRevokeHandle::getReceiptId, vo.getReceiptId()).ne(ManageRevokeHandle::getProcessStatus, ProcessStatusEnum.refuse), false);
        if (manageRevokeHandle != null) {
            log.error("该收款处理已在流程中！");
            Assert.isTrue(ProcessStatusEnum.draft.equals(manageRevokeHandle.getProcessStatus()), "该收款处理已在流程中，不可处理！");
            manageRevokeHandle.setStartTime(new Date());
            manageRevokeHandle.setProcessStatus(ProcessStatusEnum.underReview);
            this.updateById(manageRevokeHandle);
        } else {
            manageRevokeHandle = new ManageRevokeHandle();
            BeanUtil.copyProperties(vo, manageRevokeHandle, "caseNo", "startTime", "endTime", "createBy", "createTime", "id");
            // 生成案件编号
            manageRevokeHandle.setCaseNo(CreatCaseNoUtil.GeneratorCaseNo(ContractBusinessEnum.revokeHandle));
            manageRevokeHandle.setStartTime(new Date());
            manageRevokeHandle.setProcessStatus(ProcessStatusEnum.underReview);
            this.save(manageRevokeHandle);
        }
        manageRevokeHandle.setProcessPerson(SecurityUtils.getUser().getUsername());
        manageRevokeHandle.setCaseStatus(CaseStatusEnum.UNDER_REVIEW);
        //保存待办任务记录
        saveApproveInfoProcessor.saveApproveInfo(manageRevokeHandle, ContractBusinessEnum.revokeHandle, CaseStatusEnum.UNDER_REVIEW, BusinessUrlEnum.REVOKE_HANDLE);
        //首次提交发起申请，保存审批历史记录
        contractWorkFlowSaveApproveInfoProcessor.saveApproveRecord(manageRevokeHandle, ContractBusinessEnum.revokeHandle);
        StartFlowRequest startFlowRequest = new StartFlowRequest();
        startFlowRequest.setAfsFlowKey(AfsEnumUtil.key(WorkflowTypeEnum.REVOKE_HANDLE));
        startFlowRequest.setBizDataId(String.valueOf(manageRevokeHandle.getId()));
        startFlowRequest.setFlowName(AfsEnumUtil.desc(WorkflowTypeEnum.REVOKE_HANDLE));
        String json = JSONObject.toJSONString(manageRevokeHandle);
        JSONObject cancelJson = JSONObject.parseObject(json);
        workflowService.startWorkFlow(startFlowRequest, cancelJson);
        corporateTransferFeign.revokeHandleStart(manageRevokeHandle.getReceiptId(), AfsEnumUtil.key(manageRevokeHandle.getTreatmentMethod()), manageRevokeHandle.getCaseNo());
        return Boolean.TRUE;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean revokeHandleSubmitProcess(ManageRevokeHandleVo manageRevokeHandleVo) {
        ManageRevokeHandle manageRevokeHandle = this.getById(manageRevokeHandleVo.getId());
        if (manageRevokeHandle == null) {
            log.error("收据不存在！");
            Assert.isTrue(false, "收据不存在！");
        }
        //更新处理状态
        if (AfsEnumUtil.key(NormalSubmitEnum.SUGGEST_CHECK_FINAL).equals(manageRevokeHandleVo.getApprovalOperating())) {
            WorkTaskCreatedInfo workTaskCreatedInfo = workTaskCreatedInfoService.getOne(Wrappers.<WorkTaskCreatedInfo>query().lambda()
                            .eq(WorkTaskCreatedInfo::getBizDataId, manageRevokeHandle.getId())
                            .orderByDesc(WorkTaskCreatedInfo::getCreateTime)
                    , false
            );
            if(ProcessStatusEnum.toBeRepaired.equals(manageRevokeHandle.getProcessStatus())){
                manageRevokeHandle.setRefundBankCode( manageRevokeHandleVo.getRefundBankCode() );
                manageRevokeHandle.setPayer( manageRevokeHandleVo.getPayer() );
                manageRevokeHandle.setRefundAccount( manageRevokeHandleVo.getRefundAccount() );
                manageRevokeHandle.setBranchBank(  manageRevokeHandleVo.getBranchBank());
                manageRevokeHandle.setBankNo(  manageRevokeHandleVo.getBankNo());
                manageRevokeHandle.setTreatmentMethod( manageRevokeHandleVo.getTreatmentMethod() );
            }
            //最后节点流程审批完成 或处理方式为收入时，任务备忘录为end，流程结束
            if (ProcessStatusEnum.approved.name().equals(workTaskCreatedInfo.getTaskMemo()) ||
                    (ProcessStatusEnum.end.name().equals(workTaskCreatedInfo.getTaskMemo()) && TreatmentMethodEnum.INCOME.equals(manageRevokeHandle.getTreatmentMethod()))) {
                manageRevokeHandle.setProcessStatus(ProcessStatusEnum.approved);
                manageRevokeHandle.setCaseStatus(CaseStatusEnum.APPROVED);
                manageRevokeHandle.setEndTime(new Date());
                manageRevokeHandle.setEndDate(new Date());
                saveApproveInfoProcessor.saveApproveInfo(manageRevokeHandle, ContractBusinessEnum.revokeHandle, CaseStatusEnum.APPROVED, BusinessUrlEnum.REVOKE_HANDLE);
                IResponse iResponse = corporateTransferFeign.revokeHandleAgree(manageRevokeHandle.getReceiptId());
                Assert.isTrue(CommonConstants.SUCCESS.equals(iResponse.getCode()), "收款撤销通过处理失败");
            } else {
                manageRevokeHandle.setProcessStatus(ProcessStatusEnum.underReview);
                manageRevokeHandle.setCaseStatus(CaseStatusEnum.UNDER_REVIEW);
                saveApproveInfoProcessor.saveApproveInfo(manageRevokeHandle, ContractBusinessEnum.revokeHandle, CaseStatusEnum.UNDER_REVIEW, BusinessUrlEnum.REVOKE_HANDLE);
            }

        } else if (AfsEnumUtil.key(NormalSubmitEnum.SUGGEST_REJECT_FINAL).equals(manageRevokeHandleVo.getApprovalOperating())) {
            manageRevokeHandle.setProcessStatus(ProcessStatusEnum.refuse);
            manageRevokeHandle.setCaseStatus(CaseStatusEnum.REFUSE);
            manageRevokeHandle.setEndTime(new Date());
            manageRevokeHandle.setEndDate(new Date());
            //保存待办任务记录
            saveApproveInfoProcessor.saveApproveInfo(manageRevokeHandle, ContractBusinessEnum.revokeHandle, CaseStatusEnum.REFUSE, BusinessUrlEnum.REVOKE_HANDLE);
            IResponse iResponse = corporateTransferFeign.revokeHandleReject(manageRevokeHandle.getReceiptId());
            Assert.isTrue(CommonConstants.SUCCESS.equals(iResponse.getCode()), "收款撤销拒绝处理失败");
        } else if (AfsEnumUtil.key(NormalSubmitEnum.SEND_BACK).equals(manageRevokeHandleVo.getApprovalOperating())) {
            //保存待办任务记录
            WorkTaskCreatedInfo workTaskCreatedInfo = workTaskCreatedInfoService.getOne(Wrappers.<WorkTaskCreatedInfo>query().lambda()
                            .eq(WorkTaskCreatedInfo::getBizDataId, manageRevokeHandle.getId())
                            .orderByDesc(WorkTaskCreatedInfo::getCreateTime)
                    , false
            );
            if(ProcessStatusEnum.approved.name().equals(workTaskCreatedInfo.getTaskMemo()) ){
                manageRevokeHandle.setProcessStatus(ProcessStatusEnum.underReview);
            }else{
                manageRevokeHandle.setProcessStatus(ProcessStatusEnum.toBeRepaired);
            }
            manageRevokeHandle.setCaseStatus(CaseStatusEnum.UNDER_REVIEW);
            saveApproveInfoProcessor.saveApproveInfo(manageRevokeHandle, ContractBusinessEnum.revokeHandle, CaseStatusEnum.UNDER_REVIEW, BusinessUrlEnum.REVOKE_HANDLE);
        }
        this.updateById(manageRevokeHandle);
        manageRevokeHandle.setProcessPerson(SecurityUtils.getUser().getUsername());;
        manageRevokeHandle.setDepartment(manageRevokeHandleVo.getDepartment());
        //流程审批
        TaskSubmitVO vo = new TaskSubmitVO();
        String json = JSONObject.toJSONString(manageRevokeHandle);
        JSONObject cancelJson = JSONObject.parseObject(json);
        vo.setBizData(cancelJson);
        vo.setApprovalOperating(manageRevokeHandleVo.getApprovalOperating());
        vo.setApprovalOpinion(manageRevokeHandleVo.getApprovalOpinion());
        vo.setReasonType(manageRevokeHandleVo.getReasonType());
        workflowSubmitService.submit(vo);
        return Boolean.TRUE;
    }

    @Override
    public IPage<ManageRevokeHandleVo> getManageHandleList(Page page, ManageCollectCancelCondition condition) {
        return this.baseMapper.getManageHandleList(page, condition);

    }

}
